home *** CD-ROM | disk | FTP | other *** search
/ Cracking 2 / Cracking II..iso / Texty / crackme / Level3.txt < prev    next >
Encoding:
Text File  |  1998-05-09  |  6.8 KB  |  155 lines

  1. [ Cracking Level-3  Your Second Key Generator ]
  2. ===============================================
  3.  
  4. For this registration you'll need to set a different break point!
  5. This time you'll need to use GetWindowTextA, CString objects requires
  6. to use this for getting the entered text.
  7. This registration is to ease you into the next level, which it
  8. deals with indirect memory referencing.  In C, it's call a pointer to
  9. a pointer.  That's sort of like a CString, in which this registration 
  10. routine uses for string storage.  And it requires memory allocation, and
  11. reallocation when it needs to.
  12.  
  13. Conventional pointer to a string.  EAX = 0x00332211
  14.  ADDRESS: EAX ---> (00332211)
  15. CONTENTS:          "Some character string here!"
  16.  
  17. Here is how a pointer to a pointer works.  EAX = 0x00012345
  18.  ADDRESS: EAX ---> (00012345)       (00332211)
  19. CONTENTS:          [00332211]  --->  "Some character string here!"
  20.  
  21. You should also know that what ever stored in the memory is in reverse
  22. order.  Only when it gets transfer to the registers then it's in the
  23. correct order.  For example, when EAX = 0x00012345, this is a pointer to
  24. a pointer to a memory.  So after you do a "d eax", on the data window
  25. you should see a 4 bytes arrangement on the memory that reads "11 22 33 00".
  26. Now since EAX is a pointer to a pointer, the content of this memory
  27. should be the final poniter to the memory string.  Then to view this
  28. memory string, do a "d 00332211", that will display the string in the
  29. data window.  Instead of typing in "d 11223300", you typed in "d 00332211"
  30. that is becaue the 4 bytes are stored in reverse order!
  31.  
  32. If you don't know what the heck a pointer to pointer is, don't worry. 
  33. You don't really need to know it.  The point of this registration is to show
  34. you another way that a program can obtain and store the user entered text.
  35. And cracking the registration should just be the same as what you did from 
  36. the previous.
  37.  
  38. See if you can trace through the entire code.  And try to constantly
  39. display the memory as much as you can to spot the registration code.
  40.  
  41. --------------------------------------------------------------------------
  42.  
  43. :00401C2B BE45632781      mov esi, 81276345  ; initial value!!!
  44.  
  45. :00401C7E E8670F0000      Call 00402BEA  ; MFC42.GetWindowTextA
  46. :00401C83 8B6C2418        mov ebp, dword ptr [esp+18]
  47. :00401C87 8B55F8          mov edx, dword ptr [ebp-08]
  48. :00401C8A 83FA05          cmp edx, 00000005  ; make sure username is >= 5 char
  49. :00401C8D 7D11            jge 00401CA0
  50. :00401C8F 6A40            push 00000040
  51. :00401C91 6804514000      push 00405104
  52. :00401C96 68D8504000      push 004050D8
  53. :00401C9B E9E2000000      jmp 00401D82
  54.  
  55. :00401CA0 33C0            xor eax, eax
  56. :00401CA2 3BD3            cmp edx, ebx
  57. :00401CA4 7E3C            jle 00401CE2
  58. :00401CA6 B901000000      mov ecx, 00000001
  59. :00401CAB 33FF            xor edi, edi
  60. :00401CAD 2BCD            sub ecx, ebp
  61. :00401CAF 894C241C        mov dword ptr [esp+1C], ecx
  62.  
  63.                           ; this parts computes the secret key value!
  64.                           ; value is stored into ESI
  65.                           ; ESI has been previously initialized with 0x81276345
  66. :00401CB3 0FBE5C0500      movsx ebx, byte ptr [ebp+eax]
  67. :00401CB8 8D4C0500        lea ecx, dword ptr [ebp+eax]
  68. :00401CBC 03F3            add esi, ebx
  69. :00401CBE 8BD8            mov ebx, eax
  70. :00401CC0 C1E308          shl ebx, 08
  71. :00401CC3 33F3            xor esi, ebx
  72. :00401CC5 8B5C241C        mov ebx, dword ptr [esp+1C]
  73. :00401CC9 03D9            add ebx, ecx
  74. :00401CCB 8BCF            mov ecx, edi
  75. :00401CCD 0FAFF3          imul esi, ebx
  76. :00401CD0 F7D1            not ecx
  77. :00401CD2 0FAFF1          imul esi, ecx
  78. :00401CD5 40              inc eax
  79. :00401CD6 03FA            add edi, edx
  80. :00401CD8 3BC2            cmp eax, edx
  81. :00401CDA 7CD7            jl 00401CB3
  82.  
  83. :00401CDC 8B7C2420        mov edi, dword ptr [esp+20]
  84. :00401CE0 33DB            xor ebx, ebx
  85.  
  86. ; Call 00402BE4 works pretty much the same as wsprintf(), but it is the MFC
  87. ; version for working with CString objects.  If you try to step into the call
  88. ; and trace what it is doing, you will be really confused.  Just know that
  89. ; the parameter "%lu" tells it to convert an unsigned 32-bit value to a numeric
  90. ; string.  Note that CString works like a dynamic allocated string.
  91. :00401CE2 56              push esi       ; -> value to be printed
  92. :00401CE3 8D542414        lea edx, dword ptr [esp+14] ; gets a pointer
  93. :00401CE7 682C514000      push 0040512C  ; -> "%lu"
  94. :00401CEC 52              push edx       ; -> pointer to destination string
  95. :00401CED E8F20E0000      Call 00402BE4  ; -> print value (esi) to string
  96. :00401CF2 8B74241C        mov esi, dword ptr [esp+1C] ; -> generated code
  97. :00401CF6 8B442420        mov eax, dword ptr [esp+20] ; -> password entered
  98. :00401CFA 83C40C          add esp, 0000000C
  99.  
  100. ; this part is the MFC version of compare string.  It is a little bit different
  101. ; from lstrcmpA, but works pretty much the same.  However it doesn't return any 
  102. ; value. If the strings match up to the last byte, then they are equal!
  103. :00401CFD 8A10            mov dl, byte ptr [eax]
  104. :00401CFF 8ACA            mov cl, dl
  105. :00401D01 3A16            cmp dl, byte ptr [esi]
  106. :00401D03 751C            jne 00401D21
  107. :00401D05 3ACB            cmp cl, bl
  108. :00401D07 7414            je 00401D1D
  109. :00401D09 8A5001          mov dl, byte ptr [eax+01]
  110. :00401D0C 8ACA            mov cl, dl
  111. :00401D0E 3A5601          cmp dl, byte ptr [esi+01]
  112. :00401D11 750E            jne 00401D21
  113. :00401D13 83C002          add eax, 00000002  ; eax = eax + 2
  114. :00401D16 83C602          add esi, 00000002  ; esi = esi + 2
  115. :00401D19 3ACB            cmp cl, bl   ; (cl - bl) test for zero
  116. :00401D1B 75E0            jne 00401CFD ; loop if not finish comparing
  117. :00401D1D 33C0            xor eax, eax
  118. :00401D1F EB05            jmp 00401D26
  119.  
  120.  
  121. Solution to the registration routine taken from my C++ source file.
  122. --------------------------------------------------------------------
  123.   register DWORD sum = 0x81276345;
  124.   register int i, slen;
  125.   CString usrn = "", key = "", keystr = "";
  126.  
  127.   GetDlgItemText(IDC_USRN, usrn);
  128.   GetDlgItemText(IDC_KEY, key);
  129.   if ((slen = usrn.GetLength()) < 5)
  130.   {
  131.     MessageBox("User Name must have at least 5 characters.",
  132.     "CrackMe", MB_OK | MB_ICONINFORMATION);
  133.     return;
  134.   }
  135.   for (i = 0; i < slen; i++)
  136.   {
  137.     sum += usrn[i];  // Adding
  138.     sum ^= (i << 8); // XORing
  139.     sum *= ((i+1) * ~(slen * i));  // '~' means ones complement negation
  140.   }
  141.   keystr.Format("%lu", sum);
  142.   if (key.Compare(keystr) == 0)
  143.   {
  144.     // correct registration code! 
  145.   }
  146.   else
  147.   {
  148.     // incorrect registration code!
  149.   }
  150.  
  151. Sample of Key Generator
  152. -----------------------
  153. You need everything up to the point that says "keystr.Format("%lu", sum);"
  154. Display the string keystr[], and you'll have the registration code!
  155.